{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 基于 MindSpore Quantum 实现量子 Q-JPEG 算法\n",
    "\n",
    "## 1 课题背景：\n",
    "\n",
    "图像压缩技术可以在保证可视化质量的同时降低处理、储存和传输图像的资源消耗。不仅在经典场景中，在量子机器学习场景，如量子卷积神经网络，也涉及图像处理任务。故而也需要图像压缩技术，以增强图像处理能力。\n",
    "\n",
    "## 2 项目任务及实现方案：\n",
    "\n",
    "本项目的核心任务是实现一种新型的量子图像压缩处理算法 — Q-JPEG [1]。类似于经典的 JPEG 图像压缩技术，Q-JPEG 可以有效过滤掉图像中的高频分量，实现对图像的压缩。但由于压缩过程基于量子傅里叶变换，相比经典 JPEG 算法，Q-JPEG 具有指数级的加速效果。基于 Q-JPEG，可实现对经典及量子图像的高效压缩，并可进一步应用于图像识别等计算机视觉任务。\n",
    "\n",
    "本项目基于 MindSpore Quantum 量子计算框架实现了该 Q-JPEG 算法，探索不同类型图像、及不同压缩比下的图像处理效果。\n",
    "\n",
    "### Q-JPEG 算法\n",
    "\n",
    "![circ](./images/circ.png)\n",
    "\n",
    "图 1：Q-JPEG 算法流程示意图 *(图片来源: arXiv:2306.09323)*\n",
    "\n",
    "Q-JPEG 算法的整体流程如图 1 所示。具体的，操作流程为：\n",
    "\n",
    "1. 使用振幅编码，将经典图像编码为量子态；\n",
    "2. 对量子态施加量子傅里叶变换，将图像从空域转换到频域；\n",
    "3. 丢弃部分高位量子比特，保留图像的低频部分并对图像进行压缩；\n",
    "4. 对剩余量子比特施加傅里叶逆变换；\n",
    "5. 丢弃部分携带冗余信息的量子比特，进一步对图像进行压缩。\n",
    "\n",
    "其中，Hadamard 变换层为可选操作。\n",
    "\n",
    "### 算法实现及效果\n",
    "\n",
    "下面基于 MindSpore Quantum 实现该算法。我们考虑将一幅图 2  所示，原始尺寸为 64*64 的 png 格式的灰度图进行压缩，并比较不同压缩比下的效果。\n",
    "\n",
    "<img src=\"./images/ms_64_bin.png\" alt=\"ms_64_bin\" width=\"200\" />\n",
    "\n",
    "图 2：待处理的灰度图示例\n",
    "\n",
    "#### 1. 图片加载\n",
    "\n",
    "png 图片共有四个通道，我们只选用其中第一个通道进行处理。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "from mindquantum.simulator import Simulator\n",
    "from mindquantum.core.circuit import Circuit, dagger, NoiseChannelAdder\n",
    "from mindquantum.algorithm import qft\n",
    "from mindquantum.utils import normalize\n",
    "from mindquantum.core.gates import AmplitudeDampingChannel\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "ms_64_bin_4 = Image.open('./images/ms_64_bin.png')  # 读取PNG图片\n",
    "ms_64_bin_array = np.array(ms_64_bin_4)[:, :, 0]  # 只选用第一通道的数据，并转换为numpy数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2. 定义操作比特\n",
    "\n",
    "如图 1 所示，我们需要预先定义好处理前后所用量子比特，以及抛弃哪些比特。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "n_qubits = 12  # 原图所用比特数\n",
    "m_qubits = 10  # 现图所用比特数\n",
    "half_diff = (n_qubits - m_qubits) // 2  # 每次抛弃掉的比特数 1\n",
    "former_qubits = list(range(0, n_qubits // 2))  # 前半部分的比特 [0,1,2,3,4,5]\n",
    "latter_qubits = list(range(n_qubits // 2, n_qubits))  # 后半部分的比特 [6,7,8,9,10,11]\n",
    "mid_qubits = former_qubits[len(former_qubits) - half_diff :]  # 前半部分中要抛弃的比特 [5]\n",
    "last_qubits = latter_qubits[len(latter_qubits) - half_diff :]  # 后半部分中要抛弃的比特 [11]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3. 振幅编码\n",
    "\n",
    "通过使用振幅编码技术，该图片可用一个 12  量子比特的系统进行编码。振幅编码过程可使用振幅编码线路制备，不过由于该过程不是本任务的核心环节，所以我们也可以直接使用归一化函数来产生，并将该量子态赋值给模拟器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = ms_64_bin_array.reshape(\n",
    "    (\n",
    "        int(\n",
    "            2**n_qubits,\n",
    "        )\n",
    "    )\n",
    ")  # 将图片数据重整化为矢量\n",
    "state = normalize(data)  # 使用归一化函数直接将矢量转化为量子态\n",
    "sim = Simulator('mqmatrix', n_qubits)  # 使用 mqmatrix 模拟器，因为后续需要进行求偏迹运算\n",
    "sim.set_qs(state)  # 将产生的量子态赋值给模拟器\n",
    "\n",
    "## 也可以使用振幅编码线路来制备该量子态\n",
    "# encoder, parameterResolver = amplitude_encoder(data, n_qubits)\n",
    "# sim.apply_circuit(encoder, parameterResolver)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4. 执行 QJPEG 算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "circ = Circuit()\n",
    "circ += qft(range(n_qubits))  # 傅里叶变换\n",
    "circ += dagger(qft(range(n_qubits - half_diff)))  # 傅里叶逆变换\n",
    "\n",
    "sim.apply_circuit(circ)\n",
    "rho = sim.get_partial_trace(mid_qubits + last_qubits)  # 对抛弃的比特求偏迹\n",
    "sub_pros = rho.diagonal().real  # 剩余密度矩阵的对角线元素即为不同结果出现的概率"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 5. 结果可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x1379c3ee0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "new_figure = sub_pros.reshape((2 ** (m_qubits // 2), -1))  # 转换为 32 * 32 的数组\n",
    "plt.imshow(new_figure)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样，如果我们设置 `m_qubits = 8` (更大压缩比)，可获得的图像如下图所示。该图的尺寸为 16* 16 可见更大压缩比下，失真更明显。\n",
    "\n",
    "<img src=\"./images/ms_16.png\" alt=\"ms_16\" width=\"200\" />\n",
    "\n",
    "#### 6. 噪声分析\n",
    "\n",
    "由于当前 NISQ 时期，量子系统不可避免地受到噪声影响，会产生不完美的输出结果。接下来我们讨论不同噪声强度下，QJPEG 算法的实现效果。需要指出的是，此处我们只关注 QJPEG 算法内部对噪声的鲁棒性，而不讨论量子态制备的问题。\n",
    "\n",
    "作为展示，我们为每个量子门后后面都添加一个不同强度的振幅衰减信道，该操作可通过如下方式对量子线路进行修饰来完成。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "strength = 0.001\n",
    "channel = AmplitudeDampingChannel(strength)\n",
    "adder = NoiseChannelAdder(channel, with_ctrl=True, add_after=True)\n",
    "circ = adder(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以 `m_qubits=10` 为例，下面四图分别展示了噪声强度为 0、0.0001、0.001、0.01 下 QJPEG 对图像的处理效果。从该结果中可以看出，该算法具有一定的鲁棒性，在噪声强度小于 0.001 以下，都表现出了较好的处理结果。\n",
    "\n",
    "![noise](./images/noise.png)\n",
    "\n",
    "### 算法封装\n",
    "\n",
    "为便于后续用户使用，我们将该 QJPEG 算法封装为函数 qjpeg。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mindquantum.simulator import Simulator\n",
    "from mindquantum.core.circuit import Circuit, dagger\n",
    "from mindquantum.algorithm import qft\n",
    "from mindquantum.utils import normalize\n",
    "import numpy as np\n",
    "import matplotlib.pylab as plt\n",
    "from PIL import Image\n",
    "from typing import Union\n",
    "\n",
    "\n",
    "def qjpeg(figure: Union[str, np.ndarray], n_qubits: int, m_qubits: int) -> np.ndarray:\n",
    "    \"\"\"对输入的 *.png 图片利用 QJPEG 算法进行压缩。\"\"\"\n",
    "    if not isinstance(figure, np.ndarray):\n",
    "        if figure[-4:] != \".png\":\n",
    "            raise ValueError(\"This function supports only *.png or np.ndarry figure.\")\n",
    "        figure = np.array(Image.open(figure))[:, :, 0]\n",
    "    origin_figure = figure.reshape(-1)\n",
    "\n",
    "    if not isinstance(n_qubits, int) or not isinstance(m_qubits, int):\n",
    "        raise ValueError(\"n_qubits and m_qubits should be positive int.\")\n",
    "    if n_qubits <= 0 or m_qubits <= 0:\n",
    "        raise ValueError(\"n_qubits and m_qubits should be positive int.\")\n",
    "    if n_qubits <= m_qubits:\n",
    "        raise ValueError(\"m_qubits should little than n_qubits.\")\n",
    "    if np.log2(origin_figure.shape[0]) != n_qubits:\n",
    "        print(np.log2(origin_figure.shape[0]))\n",
    "        raise ValueError(\"the pixel number of the input figure should equal to 2**n_qubits.\")\n",
    "    if (n_qubits - m_qubits) % 2 != 0:\n",
    "        raise ValueError(\"the different between n_qubits and m_qubits should be even.\")\n",
    "\n",
    "    half_diff = (n_qubits - m_qubits) // 2  # 每次抛弃掉的比特数\n",
    "    former_qubits = list(range(0, n_qubits // 2))  # 前半部分的比特\n",
    "    latter_qubits = list(range(n_qubits // 2, n_qubits))  # 后半部分的比特\n",
    "    mid_qubits = former_qubits[len(former_qubits) - half_diff :]  # 前半部分中要抛弃的比特\n",
    "    last_qubits = latter_qubits[len(latter_qubits) - half_diff :]  # 后半部分中要抛弃的比特\n",
    "\n",
    "    state = normalize(origin_figure)\n",
    "    sim = Simulator('mqmatrix', n_qubits)\n",
    "    sim.set_qs(state)\n",
    "\n",
    "    circ = Circuit()\n",
    "    circ += qft(range(n_qubits))\n",
    "    circ += dagger(qft(range(n_qubits - half_diff)))\n",
    "    sim.apply_circuit(circ)\n",
    "    rho = sim.get_partial_trace(mid_qubits + last_qubits)\n",
    "    sub_pros = rho.diagonal().real\n",
    "    new_figure = sub_pros.reshape((2 ** (m_qubits // 2), -1))\n",
    "    return new_figure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 案例测试\n",
    "\n",
    "作为案例，我们使用两个网格图对该函数进行测试。在输出结果中，我们对处理前后的图像进行了可视化处理。结果显示，与预期结果一致，达到算法设计要求。\n",
    "\n",
    "#### 测试案例一"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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FN/vv/9eUvWHhHzlgQce0Ny5c3XnnXfq4YcfVvv27fX222+7rsA/v9777rtP77//vm688UaNHTtW+/fv17Jly+r8XVmtVr3++utKSkpSz549lZKSog4dOujw4cPatGmTwsPD9cknn3jlc6J2S5cuVUpKimw2m/bv368OHTq4vT506FAVFhZq9+7dPqrw/+vYsmVLla99++23jVxN00eIVOH222/XFVdcoczMTFdwXHbZZRo2bJieeuopXXnllfVa/1tvvaXIyEi98847ysrKUkJCglauXKnu3bubao/iTS1bttTGjRs1efJkzZkzRy1bttSECRN07bXXasyYMW71JiYm6qWXXtKsWbM0ZcoU9e3bV6tXr9ajjz5a5+0NHTpU27Zt03PPPae5c+eqtLRUkZGR6t+/v+lDiGhYZWVlmjlzpt/uPUvnTh7JzMysNB4VFaXp06dr6tSpPqiqaaLtiZ/Iy8vTH//4Ry1btkx33323r8up1ezZs/XII4/op59+qvSLFE1TxZ5Inz599O233+rHH39UVFSU63V/2hPxhzou5HQ6debMGb/7oVhfzIn4wKlTpyqNzZ49W1arVYMHD/ZBRTW7sN7Tp09rwYIF6tatGwFyEXrqqadUXl6umTNn1mn5ZcuWKS4uTs2bN1fr1q11xx13uM2TvfzyywoKCnI7KeOll16SxWJRenq6a6y8vFxhYWF68skn61V/fVoRTZw4UTExMXVap8ViUVpamt5++2317NlTNpvNdZ3Y4cOHde+99yoiIkI2m009e/bU4sWL6/W5fIXDWT7wwgsvKDc3V8OGDVOzZs20Zs0arVmzRn/+85/VqVMnX5dXyW233abo6Gj16dNHRUVFWrZsmfbu3au3337b16XBB7p06aIJEyZo0aJFmjp1qtveyIWef/55/e1vf9PYsWN133336fjx43rllVc0ePBgffnll7r00ks1aNAgOZ1Obd26VTfffLOkc2dBWq1W5eTkuNb15ZdfqrS0tE4/tMrLyyu19gkJCan2FPH6tiKqzsaNG/Xuu+8qLS1Nbdq0UUxMjAoKCnTNNde4QqZt27Zas2aNJk2apOLiYk2ZMqXe221Uvr1g/uL02WefGdddd53RqlUr45JLLjFiY2ONGTNmGGfPnvV1aVX697//bfTs2dNo0aKFERISYlx99dXGihUrfF0WGllFG54vvvjC2L9/v9GsWTPjoYcecr0+ZMgQo2fPnq7nBw8eNIKCgoznn3/ebT1ff/210axZM9d4eXm5ER4ebjzxxBOGYZxrf3PZZZcZt99+uxEUFGSUlJQYhmEYs2bNMqxWq/Hrr7/WWOeQIUOqbO1T0ZKnPq2IkpOTjc6dO1fa5oXrNIxzLYasVquxZ88et/FJkyYZ7du3NwoLC93G77jjDsNut7u1AgoEHM7ygREjRmjr1q365ZdfdObMGe3bt08ZGRlq1sw/dwynTJmi3bt3q7S0VKdOnVJubq7GjRvn67LgQ127dtU999yjhQsX6siRI1Uu8+GHH8rpdGrs2LGuFjaFhYWKjIxUt27dXE08rVarrr32WmVnZ0s6dwbViRMnNHXqVBmGoW3btkk6t3dy5ZVX6tJLL621vpiYmEqtfZ544okql22IVkTVGTJkiHr06OF6bhiGPvjgA40cOVKGYbh9L4mJiSoqKtKuXbvqvd3G5J//1wLg96ZPn67//Oc/mjlzpubMmVPp9R9++EGGYbhdVHu+Sy65xPXvgwYN0owZM3Tq1Cnl5OSoffv2uvrqq9W7d2/l5OS4fniNHTu2TrW1aNHCo9Y+9W1FVJ0L13n8+HH99ttvWrhwoRYuXFjle44dO1bv7TYmQgSAKV27dtX48eO1cOHCKk+ZdTqdslgsWrNmTZVtb86fnxg4cKDOnj2rbdu2KScnx9VgdNCgQcrJydHevXt1/Pjxam/R0Fhqau1Tlepa+4wfP77aHnG9evWqR4WNjxABYNr06dO1bNky/fOf/6z0WmxsrAzDUJcuXfSHP/yhxvXEx8crODhYOTk5ysnJcXWEGDx4sBYtWqQNGza4njc0T1oR1dTapy7atm2rsLAwlZeXN5nWPsyJADAtNjZW48eP14IFC3T06FG312677TYFBQXp2WefrdQc1DAMt7ZCISEh6tevn9555x3973//c9sTOXXqlF5++WXFxsaqffv2Df4ZPGlFFBsbq6KiIrcmrUeOHFFWVladthUUFKQxY8bogw8+qPI6lkBs7dNkQmTevHmKiYlRSEiI+vfvrx07dvi6pBplZ2dr5MiRioqKksVi0apVq3xdUq0yMzPVr18/hYWFqV27drrlllv03Xff+bqsWs2fP1+9evVSeHi4wsPDNWDAAK1Zs8bXZTUZTz/9tM6ePVvpbyE2NlZ///vftXz5cg0cOFAvvviiXnvtNT355JPq3r27lixZ4rb8oEGD9N1338lut+uqq66SJLVr107du3fX999/77VDWee3IpowYYJeffVVjRs3Tnl5eZLcD2HdcccdatGihW699VbNmTNHmZmZ6t+/f617WuebOXOm2rdvr/79+2vKlClauHChZs6cqbFjx6p79+4N/fG8rkmEyMqVK5Wenq6MjAzt2rVLvXv3VmJiol9PUDkcDvXu3Vvz5s3zdSl1tmXLFqWmpmr79u1av369zp49qxtuuEEOh8PXpdWoY8eOmjlzpnJzc7Vz504NHz5co0eP1p49e3xdWpNw+eWXa/z48VW+NnXqVH3wwQeyWq169tln9dhjj+njjz/WDTfc4HajM0mukLj22mtltVorjXtzPuStt95SamqqPv30Uz355JM6c+aMVq5cKUluV5hfdtllysrKUmhoqJ544gm9+eabyszM1MiRI+u8rYiICO3YsUMpKSn68MMPlZaWpjlz5uiXX36p8rCg3/Ph6cUNJj4+3khNTXU9Ly8vN6KioozMzEwfVlV3koysrCxfl+GxY8eOGZKMLVu2+LoUj7Vq1cp4/fXXfV0G/NiXX35pSDKWLVvm61L8WsDviZw5c0a5ubluk1RWq1UJCQmu88vhHUVFRZKk1q1b+7iSuisvL9eKFSvkcDg0YMAAX5cDPxForYj8ScCfnVVYWKjy8nJFRES4jUdERGjv3r0+qqrpczqdmjJliq677rp6dzVuDF9//bUGDBig06dPq2XLlsrKynK7CAwXt0BrReRPAj5E4BupqanavXu3tm7d6utS6qR79+7Ky8tTUVGR3n//fSUnJ2vLli0ECSSdm4dZv369nnvuOZWWlio6OlozZszQ008/7evS/F7Ah0ibNm0UFBSkgoICt/GCggJFRkb6qKqmLS0tTatXr1Z2drY6duzo63LqJDg42HUFclxcnL744gvNmTNHCxYs8HFl8AcjRozQiBEjfF1GQAr4OZHg4GDFxcW5LkaSzh1q2bBhA8e8G5hhGEpLS1NWVpY2btxYqaVDIHE6nSorK/N1GUDAC/g9EUlKT09XcnKy+vbtq/j4eM2ePVsOh0MpKSm+Lq1apaWlblfEHjhwQHl5eWrdurWio6N9WFn1UlNTtXz5cn300UcKCwtzXVxmt9srtXfwJ9OmTVNSUpKio6NVUlKi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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "figure = np.array([[1, 0, 0, 0], [1, 1, 0, 0], [1, 1, 1, 0], [1, 1, 1, 1]])\n",
    "n_qubits = 4  # 原图所用量子比特数\n",
    "m_qubits = 2  # 现图所用量子比特数\n",
    "\n",
    "new_figure = qjpeg(figure, n_qubits, m_qubits)\n",
    "fig = plt.figure()\n",
    "p_0 = fig.add_subplot(121)\n",
    "s1 = p_0.matshow(figure, cmap=plt.cm.gray)\n",
    "plt.title(\"Origin Figure\")\n",
    "\n",
    "p_1 = fig.add_subplot(132)\n",
    "s1 = p_1.matshow(new_figure, cmap=plt.cm.gray)\n",
    "plt.title(\"New Figure\")\n",
    "plt.subplots_adjust(left=0, bottom=0.5, right=1, wspace=0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 测试案例二"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "figure = np.zeros((8, 8))\n",
    "figure[:2, :2] = 1\n",
    "figure[4:6, :2] = 1\n",
    "figure[:2, 4:6] = 1\n",
    "figure[2:4, 2:4] = 1\n",
    "figure[6:8, 2:4] = 1\n",
    "figure[4:6, 4:6] = 1\n",
    "figure[6:8, 6:8] = 1\n",
    "figure[2:4, 6:8] = 1\n",
    "\n",
    "n_qubits = 6  # 原图所用量子比特数\n",
    "m_qubits = 4  # 现图所用量子比特数\n",
    "\n",
    "new_figure = qjpeg(figure, n_qubits, m_qubits)\n",
    "fig = plt.figure()\n",
    "p_0 = fig.add_subplot(121)\n",
    "s1 = p_0.matshow(figure, cmap=plt.cm.gray)\n",
    "plt.title(\"Origin Figure\")\n",
    "\n",
    "p_1 = fig.add_subplot(132)\n",
    "s1 = p_1.matshow(new_figure, cmap=plt.cm.gray)\n",
    "plt.title(\"New Figure\")\n",
    "plt.subplots_adjust(left=0, bottom=0.5, right=1, wspace=0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 项目总结\n",
    "\n",
    "综上所述，本项目基于 MindSpore Quantum 实现了 QJPEG 算法，并比较了不同压缩比下的图像处理效果，对算噪声鲁棒性进行了分析。此外，我们对该算法进行了函数封装，并利用具体的测试案例对该函数进行了测试，结果与预期一致。\n",
    "\n",
    "## 参考文献\n",
    "\n",
    "[1] arXiv:2306.09323 [quant-ph] https://doi.org/10.48550/arXiv.2306.09323"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py39",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
